package com.cskaoyan.javase.oop3._2inner._3local._3notice;

/**
 * 使用局部内部类的细节问题：
 * 当你在局部内部类当中，去修改方法的局部变量时，会编译报错：
 * Variable 'a' is accessed from within inner class, needs to be final or effectively final
 * 要想在局部内部类当中，访问方法的局部变量a：
 *      那么这个a必须是final修饰的常量或者实际意义上的final（只要不写代码修改，就是实际意义上的常量）
 *
 * 为什么会这样？
 *      首先这是因为局部变量和对象的生命周期有冲突
 *      完全可能出现方法出栈后，局部变量销毁。但对象仍然存在，还需要访问该局部变量的情况
 *      所以在这里，编译器就将该局部变量作为局部内部类对象中的成员变量，复制了一份
 *      这样就解决了生命周期的冲突问题。
 *
 * 继续往下推：
 *      我们用：把方法的局部变量作为对象中的成员变量的方式，解决了生命周期的问题。
 *      但是这样就存在取值同步的问题：
 *          如果允许在局部内部类当中修改局部变量的取值，从内存中来说
 *          实际上修改的是成员变量的取值
 *          但从代码上来说，修改的是局部变量的取值
 *          于是需要同步这个修改,否则在代码逻辑上就会存在逻辑漏洞。
 *          但是Java的设计者没有采用同步的方案，而是直接禁止修改
 *          把该局部变量设置为final
 *          这样就既解决了生命周期的问题，也无需考虑同步，两全其美。
 *
 * 补充：
 *      在Java8之前的版本，局部内部类中访问的局部变量，必须直接使用final修饰
 *      在Java8之后，程序员无需这么做，但这个局部变量本质上还是final修饰
 *          只不过加final的过程被底层替代了
 *          这是一种语法糖
 *
 * @since 15:42
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
}

class EnclosedClazz {
    public void test() {
        // 方法中定义局部变量a
        int a = 10;
        class Inner {
            public void testInner() {
                System.out.println(a);
                // a = 100;
            }
        }
    }
}